﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using MsDemo.Shared;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using ProductManagement;
using System;
using System.Net.Http;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.FeatureManagement;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.IdentityModel.Web;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.IdentityServer;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Volo.Blogging;

namespace BackendAdminAppGateway.Host
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpIdentityHttpApiModule),
        typeof(AbpIdentityHttpApiClientModule),
        typeof(ProductManagementHttpApiModule),
        //typeof(AbpEntityFrameworkCoreSqlServerModule),
        typeof(AbpEntityFrameworkCoreMySQLModule),
        typeof(AbpPermissionManagementEntityFrameworkCoreModule),
        typeof(AbpPermissionManagementApplicationModule),
        typeof(AbpPermissionManagementHttpApiModule),
        typeof(AbpSettingManagementEntityFrameworkCoreModule),
        typeof(BloggingApplicationContractsModule),
        typeof(AbpPermissionManagementDomainIdentityModule),
        typeof(AbpPermissionManagementDomainIdentityServerModule),
        typeof(AbpHttpClientIdentityModelWebModule),
        typeof(AbpTenantManagementApplicationContractsModule),
        typeof(AbpTenantManagementHttpApiModule),
        typeof(AbpTenantManagementHttpApiClientModule),
        typeof(AbpTenantManagementEntityFrameworkCoreModule),
        typeof(AbpFeatureManagementEntityFrameworkCoreModule),
        typeof(AbpFeatureManagementApplicationModule),
        typeof(AbpFeatureManagementHttpApiModule),
        typeof(AbpAspNetCoreMvcUiMultiTenancyModule)
    )]
    public class BackendAdminAppGatewayHostModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            PreConfigure<AbpHttpClientBuilderOptions>(opt =>
            {
                base.PreConfigureServices(context);
                opt.ProxyClientBuildActions.Add((str, build) =>
                {
                    build.ConfigurePrimaryHttpMessageHandler(c =>
                    {
                        var http_handler = new HttpClientHandler()
                        {
                            AllowAutoRedirect = true,
                            ClientCertificateOptions = ClientCertificateOption.Manual,
                            ServerCertificateCustomValidationCallback =
                            (httpRequestMessage, cert, cetChain, policyErrors) =>
                            {
                                return true;
                            }
                        };
                        return http_handler;
                    });
                });
            });
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            // System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
            var configuration = context.Services.GetConfiguration();


            
            Configure<AbpMultiTenancyOptions>(options =>
            {
                options.IsEnabled = MsDemoConsts.IsMultiTenancyEnabled;
            });

            context.Services.AddAuthentication("Bearer")
                //.AddIdentityServerAuthentication(options =>
                //{
                //    options.Authority = configuration["AuthServer:Authority"];
                //    options.ApiName = configuration["AuthServer:ApiName"];
                //    options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                //    options.TokenValidationParameters.ValidateIssuer = false;

                //});
                .AddJwtBearer(options =>
                {
                    options.BackchannelHttpHandler = new HttpClientHandler
                    {
                        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                    };
                    options.Authority = configuration["AuthServer:Authority"];
                    options.Audience = configuration["AuthServer:ApiName"];
                    options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                    options.TokenValidationParameters.ValidateIssuer = false;
                });

            //context.Services.
            context.Services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo { Title = "BackendAdminApp Gateway API", Version = "v1" });
                options.DocInclusionPredicate((docName, description) => true);
                options.CustomSchemaIds(type => type.FullName);
            });

            #region HttpClientHandler
            //context.Services.AddHttpClient(Microsoft.Extensions.Options.Options.DefaultName).ConfigurePrimaryHttpMessageHandler(c =>
            //{
            //    var hander = new HttpClientHandler();
            //    hander.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;
            //    return hander;
            //});

            //context.Services.AddHttpClient("GithubHttpClient").ConfigurePrimaryHttpMessageHandler(c =>
            //{
            //    var hander = new HttpClientHandler();
            //    hander.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;
            //    return hander;
            //});

            //context.Services.AddHttpClient("AbpHttpClient").ConfigurePrimaryHttpMessageHandler(c =>
            //{
            //    var hander = new HttpClientHandler();
            //    hander.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;
            //    return hander;
            //});
            //context.Services.AddHttpClient("IdentityClient").ConfigurePrimaryHttpMessageHandler(c =>
            //{
            //    var hander = new HttpClientHandler();
            //    hander.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;
            //    return hander;
            //});

            //ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) =>
            //{
            //    // local dev, just approve all certs
            //    //if (development)
            //    return true;
            //    //return errors == SslPolicyErrors.None;
            //};
            #endregion



            context.Services.AddOcelot(configuration);

            Configure<AbpDbContextOptions>(options =>
            {
                //options.UseSqlServer();
                options.UseMySQL();
            });

            //context.Services.AddStackExchangeRedisCache(options =>
            //{
            //    options.Configuration = configuration["Redis:Configuration"];
            //});

            //var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
            //context.Services.AddDataProtection()
            //    .PersistKeysToStackExchangeRedis(redis, "MsDemo-DataProtection-Keys");
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();

            app.UseCorrelationId();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAbpClaimsMap();


            if (MsDemoConsts.IsMultiTenancyEnabled)
            {
                app.UseMultiTenancy();
            }
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "BackendAdminApp Gateway API");
                //c.DocumentTitle = "BackendAdminAppGateway_Swagger";
                c.SwaggerEndpoint("/product/swagger.json", "ProductV1");
            });

            app.MapWhen(
                ctx => ctx.Request.Path.ToString().StartsWith("/api/abp/") ||
                       ctx.Request.Path.ToString().StartsWith("/Abp/") ||
                       ctx.Request.Path.ToString().StartsWith("/api/permission-management/") ||
                       ctx.Request.Path.ToString().StartsWith("/api/feature-management/"),
                app2 =>
                {
                    app2.UseRouting();
                    app2.UseConfiguredEndpoints();
                }
            );

            app.UseOcelot().Wait();
        }
    }
}
